package com.rainkaze.lifeharbor.tools.danmaku;

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.Display;
import android.view.Gravity;
import android.view.View;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
import android.view.WindowManager;
import android.view.animation.LinearInterpolator;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.view.WindowCompat;

import com.rainkaze.lifeharbor.databinding.ActivityDanmakuDisplayBinding;

public class DanmakuDisplayActivity extends AppCompatActivity {

    private static final String TAG = "DanmakuDisplay";
    public static final String EXTRA_TEXT = "extra_text";
    public static final String EXTRA_TEXT_COLOR = "extra_text_color";
    public static final String EXTRA_BACKGROUND_COLOR = "extra_background_color";
    public static final String EXTRA_TEXT_SIZE_SP = "extra_text_size_sp";
    public static final String EXTRA_SPEED_FACTOR = "extra_speed_factor";

    private ActivityDanmakuDisplayBinding binding;
    private ObjectAnimator animator;

    @SuppressLint("SourceLockedOrientationActivity")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        try {
            binding = ActivityDanmakuDisplayBinding.inflate(getLayoutInflater());
            setContentView(binding.getRoot());

            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

            hideSystemUI();

            Bundle extras = getIntent().getExtras();
            if (extras == null) {
                Toast.makeText(this, "启动参数错误", Toast.LENGTH_LONG).show();
                finish();
                return;
            }

            String text = extras.getString(EXTRA_TEXT);
            int textColor = extras.getInt(EXTRA_TEXT_COLOR, Color.WHITE);
            int backgroundColor = extras.getInt(EXTRA_BACKGROUND_COLOR, Color.BLACK);
            float textSizeSp = extras.getFloat(EXTRA_TEXT_SIZE_SP, 100f);
            float speedFactor = extras.getFloat(EXTRA_SPEED_FACTOR, 5f);

            if (text == null) {
                text = "错误: 无文本";
            }

            if (binding.layoutDanmakuDisplayRoot == null || binding.textViewDanmakuScrollingText == null) {
                Toast.makeText(this, "布局初始化错误", Toast.LENGTH_LONG).show();
                finish();
                return;
            }

            binding.layoutDanmakuDisplayRoot.setBackgroundColor(backgroundColor);
            TextView danmakuTextView = binding.textViewDanmakuScrollingText;
            danmakuTextView.setText(text);
            danmakuTextView.setTextColor(textColor);
            danmakuTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSizeSp);

            binding.layoutDanmakuDisplayRoot.setOnClickListener(v -> {
                finish();
            });

            danmakuTextView.post(() -> {
                setupDanmakuDisplay(danmakuTextView, speedFactor);
            });

        } catch (Exception e) {
            Toast.makeText(this, "启动弹幕时发生错误: " + e.getMessage(), Toast.LENGTH_LONG).show();
            finish();
        }
    }

    private void hideSystemUI() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
            WindowInsetsController controller = getWindow().getInsetsController();
            if (controller != null) {
                controller.hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
                controller.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
            }
        } else {
            getWindow().getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_FULLSCREEN);
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            getWindow().getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
        }
    }

    private void setupDanmakuDisplay(TextView textView, float speedFactor) {
        if (textView == null) {
            return;
        }

        DisplayMetrics displayMetrics = new DisplayMetrics();
        Display display;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            display = getDisplay();
            if (display == null) {
                getWindowManager().getDefaultDisplay().getRealMetrics(displayMetrics);
            } else {
                display.getRealMetrics(displayMetrics);
            }
        } else {
            getWindowManager().getDefaultDisplay().getRealMetrics(displayMetrics);
        }
        int screenWidth = displayMetrics.widthPixels;

        textView.measure(
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
        );
        int textWidth = textView.getMeasuredWidth();

        if (textWidth == 0 && textView.getText().length() > 0) {
            textView.post(() -> setupDanmakuDisplay(textView, speedFactor));
            return;
        }

        //文本宽度小于屏幕宽度时居中显示，不滚动。
        if (textWidth < screenWidth && textWidth > 0) {
            textView.setTranslationX(0);
            FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) textView.getLayoutParams();
            params.gravity = Gravity.CENTER;
            textView.setLayoutParams(params);
            if (animator != null && animator.isRunning()) {
                animator.cancel();
            }
            return;
        }

        if (textWidth == 0) {
            FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) textView.getLayoutParams();
            params.gravity = Gravity.CENTER_VERTICAL | Gravity.START;
            textView.setLayoutParams(params);
            textView.setTranslationX(0);
            return;
        }

        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) textView.getLayoutParams();
        params.gravity = Gravity.CENTER_VERTICAL | Gravity.START;
        textView.setLayoutParams(params);


        float startX = screenWidth;
        float endX = (float) -textWidth;

        long baseDurationPerPixel = 15;
        long duration = (long) (((float) (screenWidth + textWidth) * baseDurationPerPixel) / speedFactor);
        duration = Math.max(2000, duration);
        duration = Math.min(80000, duration);

        Log.d(TAG, "setupDanmakuDisplay: startX=" + startX + ", endX=" + endX + ", duration=" + duration + "ms, speedFactor=" + speedFactor);

        if (animator != null && animator.isRunning()) {
            animator.cancel();
        }
        animator = ObjectAnimator.ofFloat(textView, "translationX", startX, endX);
        animator.setDuration(duration);
        animator.setInterpolator(new LinearInterpolator());
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.setRepeatMode(ValueAnimator.RESTART);
        animator.start();
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (animator != null && animator.isRunning()) {
            animator.pause();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        hideSystemUI();
        if (animator != null && animator.isPaused()) {
            animator.resume();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (animator != null) {
            animator.cancel();
            animator = null;
        }
        binding = null;
    }
}
